---
section: Getting Started
title: Migrate from styled-components
slug: /docs/migrate-from-styled-components/
order: 5
---

# Migrate from styled-components

Differences with styled-components and migration guide to xstyled.

<carbon-ad />

## Differences with styled-components

### Declarative components

xstyled is a kind of styled-components with super powers. It adds lot of utilities accessible on a special `x.*` component or directly using original `styled.*` syntax.

The philosophy of xstyled is to use `x.*` as much as possible.

**Using styled-components**

```js
import styled from 'styled-components'

const Button = styled.button`
  padding: 0.5rem 1rem;
  color: white;
  border-radius: 0.375rem;
  font-weight: 600;
  transition: background-color cubic-bezier(0.4, 0, 0.2, 1) 150ms;
  background-color: #10b981;

  &:hover {
    background-color: #065f46;
  }

  &:focus {
    outline: none;
    box-shadow: 0 0 0 3px #10b98180;
  }
`
```

**Using xstyled**

```jsx
import { x } from '@xstyled/styled-components'

const Button = (props) => (
  <x.button
    py={2}
    px={4}
    color="white"
    borderRadius="md"
    fontWeight="semibold"
    transition
    bg={{ _: 'emerald-500', hover: 'emerald-800' }}
    outline={{ focus: 'none' }}
    ring={{ focus: true }}
    ringColor={{ focus: 'emerald-500-a50' }}
    {...props}
  />
)
```

As you can see xstyled is fully declarative and much more productive than using styled-components.

Read [declarative components guide](/docs/declarative-components/) to learn more about this approach.

### Enhanced styled components

We know you could not be convinced by `x.*` approach. That's why xstyled could help you to be more productive with `styled.*` approach too.

Most projects follow a design system, a set of space, colors, fonts.. that define the constraints and the universe of a project.

To follow a design system with styled-components, the common way is to use the theme.

**Using styled-components**

```js
import styled from 'styled-components'

const Button = styled.button`
  padding: ${(p) => `${p.theme.space[2]} ${p.theme.space[4]}`};
  color: ${(p) => p.theme.colors.white};
  border-radius: ${(p) => p.theme.radii.md};
  font-weight: ${(p) => p.theme.fontWeights.semibold};
  transition: ${(p) => p.theme.transitions.default};
  background-color: ${(p) => p.theme.colors['emerald-500']};

  &:hover {
    background-color: ${(p) => p.theme.colors['emerald-800']};
  }

  &:focus {
    outline: none;
    box-shadow: ${(p) => p.theme.shadows['emerald-ring']};
  }
`
```

**Using xstyled**

```js
import styled from '@xstyled/styled-components'

const Button = styled.button`
  padding-top: 2;
  padding-bottom: 2;
  padding-right: 4;
  padding-left: 4;
  color: white;
  border-radius: md;
  font-weight: semibold;
  transition: default;
  background-color: emerald-500;

  &:hover {
    background-color: emerald-800;
  }

  &:focus {
    outline: none;
    box-shadow: emerald-ring;
  }
`
```

Read [enhanced styled components guide](/docs/magic-styled-components/) to learn more about this approach.

### Responsive utilities

xstyled has great responsive utilities to simplify usage of media queries.

**Using styled-components**

```js
import styled from 'styled-components'

const Button = styled.div`
  width: 200px;

  @media (min-width: 768px) {
    width: 300px;
  }
`
```

**Using xstyled's `x.*`**

```js
import { x } from '@xstyled/emotion'

const Button = ({ children }) => {
  return <x.button w={{ _: 200, md: 300 }}>{children}</x.button>
}
```

**Using xstyled's `styled.*`**

```js
import styled from '@xstyled/styled-components'

const Button = styled.div`
  width: 200;

  @media (min-width: md) {
    width: 300;
  }
`
```

## Replacing styled-components by xstyled

`@xstyled/styled-components` is a drop-in replacement for `styled-components`. You can safely replace `styled-components` by `@xstyled/styled-components`.

Once your code is using xstyled, you can start using [declarative components (`x.*`)](/docs/declarative-components/) and [enhanced styled components (`styled.*`)](/docs/styled-components/).

### `css` prop is not supported

[Styled Components `css` prop](https://styled-components.com/docs/api#css-prop) is not supported by xstyled. We don't plan to support it since xstyled philosophy is to use `x.*` instead.

Styled Components `css` prop rely on a Babel transformation to work. Some edge-cases like using state in a CSS property are not supported. We recommended to not use it. If your codebase uses it, then you should migrate to xstyled's `x.*`.

**❌ The following code does not work even with just styled-components**

```js
function Example() {
  const [value, setValue] = useState(false)
  return (
    <div
      css={`
        color: ${value ? 'red' : 'blue'};
      `}
    />
  )
}
```

## Babel plugin

You may want to use [styled-components Babel plugin](https://styled-components.com/docs/tooling#babel-plugin) to add support for server-side rendering, minification of styles, and a nicer debugging experience.

You can use it out of the box, but you have to specify xstyled as `topLevelImportPaths`:

```js
// .babelrc
{
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "topLevelImportPaths": [
          "@xstyled/styled-components",
          "@xstyled/styled-components/no-tags",
          "@xstyled/styled-components/native",
          "@xstyled/styled-components/primitives"
        ],
      }
    ]
  ]
}
```

## Babel Macro

You may want to use [styled-components Babel macro](https://styled-components.com/docs/tooling#babel-macro) to use Babel plugin with zero-configuration.

To use it, follow [styled-components guide](https://styled-components.com/docs/tooling#babel-macro) and add this configuration in your `package.json` or any other [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros) config file:

```js
// babel-plugin-macros.config.js
module.exports = {
  // ...
  // Other macros config
  styledComponents: {
    importModuleName: '@xstyled/styled-components',
  },
}
```

You don't need to specify additional `topLevelImportPaths` config when you use babel macro.
